#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

using System;
using System.Collections.Generic;
using System.Windows;
using UTable.Input;
using UTable.Input.MultiTouch;
using UTable.Objects.Handlers;

namespace UTable.Objects.Controls
{

    public class PCube: UContentControl
    {

        private MultiTouchProcessor _multiTouchProcessor;

        static PCube()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PCube), new FrameworkPropertyMetadata(typeof(PCube)));
        }

        private void OnMultiTouchDetected(MultiTouchEventArgs args)
        {
            _multiTouchProcessor.RaiseMultiTouchEvent(args);
        }

        public PCube(): base()
        {
            _multiTouchProcessor = new UTable.Objects.Handlers.MultiTouchProcessor();
            DetectContactsHandler handler = new DetectContactsHandler();
            handler.NewContact += new ContactEventHandler(handler_NewContact);
            handler.NoContact += new ContactEventHandler(handler_NoContact);
            _multiTouchProcessor.Handlers.Add(handler);
        }

        void handler_NoContact(FingerEventArgs args)
        {
            Point p = args.Position;
            this.IsPressed = false;
            if (args.EventType == FingerEventType.FINGER_UP_EVENT && p.X >= 0 && p.X <= this.ActualWidth && p.Y >= 0 && p.Y <= this.ActualHeight)
            {
                this.IsChosen = true;
                this.RaisePressedEvent(new PButtonEventArgs(p));
            }
            this.RaiseUpEvent(new PButtonEventArgs(p));
        }

        void handler_NewContact(FingerEventArgs args)
        {
            this.IsPressed = true;
            this.RaiseDownEvent(new PButtonEventArgs(args.Position));
        }

        public override void OnInputReceived(InputEventArgs args)
        {
            base.OnInputReceived(args);

            if (args is MultiTouchEventArgs)
                OnMultiTouchDetected(args as MultiTouchEventArgs);
            args.Handled = true;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

        #region MultiTouch Process Part

        void handler_OneFingerUp(List<FingerPoint> fingers)
        {
            Point p = fingers[0].Position;
            this.IsPressed = false;
            if (p.X >= 0 && p.X <= this.ActualWidth && p.Y >= 0 && p.Y <= this.ActualHeight)
            {
                this.IsChosen = true;
                this.RaisePressedEvent(new PButtonEventArgs(p));
            }
            this.RaiseUpEvent(new PButtonEventArgs(p));
        }

        void handler_OneFingerDown(List<FingerPoint> fingers)
        {
            this.IsPressed = true;
            this.RaiseDownEvent(new PButtonEventArgs(fingers[0].Position));
        }

        void handler_OneFingerMove(List<FingerPoint> oFigners, List<FingerPoint> nFingers)
        {
            if (IsPressingLocked)
                return;
        }

        #endregion

        #region events

        public event PButtonEventHandler Pressed;

        public event PButtonEventHandler Down;

        public event PButtonEventHandler Up;

        #endregion

        #region Methods

        protected void RaisePressedEvent(PButtonEventArgs args)
        {
            OnPressed(args);
            if (Pressed != null)
            {
                Pressed(this, args);
            }
        }

        protected void RaiseDownEvent(PButtonEventArgs args)
        {
            OnDown(args);
            if (Down != null)
            {
                Down(this, args);
            }
        }

        protected void RaiseUpEvent(PButtonEventArgs args)
        {
            OnUp(args);
            if (Up != null)
                Up(this, args);
        }


        protected virtual void OnPressed(PButtonEventArgs args)
        {

        }

        protected virtual void OnDown(PButtonEventArgs args)
        {

        }

        protected virtual void OnUp(PButtonEventArgs args)
        {

        }

        #endregion

        #region Properties

        public Boolean IsPressingLocked = false;

        public bool IsPressed
        {
            get { return (Boolean)GetValue(IsPressedProperty); }
            set { SetValue(IsPressedProperty, value); }
        }

        public bool IsChosen
        {
            get { return (Boolean)GetValue(IsChosenProperty); }
            set { SetValue(IsChosenProperty, value); }
        }

        #endregion

        #region Reigster Dependency Property


        public static readonly DependencyProperty IsPressedProperty =
                DependencyProperty.Register("IsPressed", typeof(Boolean), typeof(PCube));

        public static readonly DependencyProperty IsChosenProperty =
                DependencyProperty.Register("IsChosen", typeof(Boolean), typeof(PCube));


        #endregion
    }

    public delegate void PButtonEventHandler(Object sender, PButtonEventArgs args);

    public class PButtonEventArgs: EventArgs
    {
        public PButtonEventArgs(Point position)
        {
            this.Position = position;
        }

        public Point Position { get; set; }
    }
}
